\subsubsection{x86: Funkcja alloca()}
\label{alloca}
\myindex{\CStandardLibrary!alloca()}

\newcommand{\AllocaSrcPath}{C:\textbackslash{}Program Files (x86)\textbackslash{}Microsoft Visual Studio 10.0\textbackslash{}VC\textbackslash{}crt\textbackslash{}src\textbackslash{}intel}

Przypadek z funkcją \TT{alloca()} jest całkiem ciekawy
\footnote{W MSVC, implementację funkcji można podejrzeć w plikach \TT{alloca16.asm} i \TT{chkstk.asm} w \\
\TT{\AllocaSrcPath{}}}. 
Ta funkcja działa jak \TT{malloc()}, ale przydziela pamięć od razu na stosie.
Nie potrzebne jest zwalnianie pamięci \TT{free()}, dlatego że epilog funkcji~(\myref{sec:prologepilog})
przywróci \ESP do stanu początkowego i przeznaczona pamięć \IT{zostaje wyrzucona}.
Ciekawa jest również realizacja tej funkcji.
Ona, w skrócie, po prostu przesuwa \ESP wgłąb stosu i zwraca \ESP jako wskaźnik na przydzielony obszar.

Spróbujmy:

\lstinputlisting[style=customc]{patterns/02_stack/04_alloca/2_1.c}

Funkcja \TT{\_snprintf()} działa tak samo, jak i \printf, tylko zamiast wyprowadzenia wyniku na wyjście standardowe \gls{stdout} (czyli do terminalu),
ona go zapisuje do buforu \TT{buf}. Funkcja \puts, z kolei, wyrzuca zawartość buforu \TT{buf} na \gls{stdout}. Oczywiście można by było tutaj zamienić
tę parę instrukcji na \printf, ale tutaj chcielibyśmy zobaczyć wykorzystanie niewielkiego buforu.

\myparagraph{MSVC}

Skompilujmy (MSVC 2010):

\lstinputlisting[caption=MSVC 2010,style=customasmx86]{patterns/02_stack/04_alloca/2_2_msvc.asm}

\myindex{Compiler intrinsic}
Jedyny parametr \TT{alloca()} jest przekazywany przez \EAX, a nie jak zwykle, przez stos
\footnote{To dlatego, że alloca()~--- to nie tyle co funkcja, a raczej \IT{compiler intrinsic} (\myref{sec:compiler_intrinsic})
Jedną z przyczyn, flaczego tu potrzeba funkcji, a nie kilku instrukcji w samym kodzie, polega na tym, że w realizacji
funkcji alloca() w \ac{MSVC}
zawarty również kod, czytający z dopiero co przydzielonej pamięci po to, żeby \ac{OS} zaalokowała pamięć fizyczną dla tego obszaru \ac{VM}.
Po wywołaniu \TT{alloca()} \ESP wskazuje na blok o długości 600 bajtów, z którego możemy korzystać na potrzeby naszego \TT{buf}.}.

\myparagraph{GCC + \IntelSyntax}

GCC 4.4.1 nie wywołuje innych funkcji:

\lstinputlisting[caption=GCC 4.7.3,style=customasmx86]{patterns/02_stack/04_alloca/2_1_gcc_intel_O3_RU.asm}

\myparagraph{GCC + \ATTSyntax}

Spójrzmy na ten sam kod w syntaksie AT\&T:

\lstinputlisting[caption=GCC 4.7.3,style=customasmx86]{patterns/02_stack/04_alloca/2_1_gcc_ATT_O3.s}

\myindex{\ATTSyntax}
Wygląda to tak samo jak i poprzedni listing.

A propos, \INS{movl \$3, 20(\%esp)}~--- jest analogiem do \INS{mov DWORD PTR [esp+20], 3} w syntaksie Intel.
Adresowanie pamięci typu \IT{rejestr+przesunięcie} jest zapisywane w syntaksie AT\&T jako \TT{przesunięcie(\%{rejestr})}.


